package com.navinfo.platform.trip.common.arithmetic;


import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.enums.EventStatus;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.arithmetic.manager.EventConvert;
import com.navinfo.platform.trip.common.arithmetic.var.VarParking_0200;
import com.navinfo.platform.trip.common.config.ConfigMap;

import java.util.Optional;

/**
 * 实时计算：单独0200算法链的停车算法<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：事件<br/>
 * @author CAI.HS
 */
public class Parking_0200 extends AbstractArithmetic<VarParking_0200> {
    /**
     * 事件类型
     */
    private static final EventType EVENT_TYPE = EventType.parking_0200;
    /**
     * 时长阀值，单位ms
     */
    private long timeThresholdMs = ConfigMap.getLong("0200_Parking_Time");

    /**
     * 判断当前点是否为停车状态
     */
    private boolean isCurrentParking() {
        CommonData data = getCommonData();
        // ACC状态为OFF or (ACC状态为ON and 车速=0)
        return !data.isAcc() || data.getSpeedKmh() == 0;
    }

    @Override
    public void calculate() {
        logger.debug("进入0200停车算法.[terminalId:{}]", terminalId);
        VarParking_0200 var = getObj();

        boolean previousIdle = var.isPreParking();
        boolean currentIdle = isCurrentParking();
        var.setPreParking(currentIdle);
        logger.debug("0200停车算法，停车状态：previousIdle:{},currentIdle:{}.[terminalId:{}]", previousIdle, currentIdle, terminalId);

        //算法计算
        switch (super.getEventStatus(previousIdle, currentIdle)) {
            case START:
                logger.debug("0200停车算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(EVENT_TYPE);
                break;
            case IN:
                logger.debug("0200停车算法，事件中...");
                calcEventData(EVENT_TYPE);
                break;
            case END:
                logger.debug("0200停车算法，事件结束...");
                calcEventData(EVENT_TYPE);
                endEvent();
                break;
            default:
                logger.debug("0200停车算法，停车状态：上一次和本次都未停车，跳出算法.[terminalId:{}]", terminalId);
        }

        logger.debug("0200停车算法结束.[terminalId:{}]", terminalId);
    }

    @Override
    public void calcEventData(EventType eventType) {
        Optional.ofNullable(drivingData.getEventData(eventType)).ifPresent(eventData -> {
            //累加里程、油耗、时长
            EventConvert.convertCommonField(eventData, drivingData);
            eventData.setExtendField03(Optional.ofNullable(eventData.getExtendField03()).orElse(0) + getCommonData().getDffTime());

            if (eventData.getExtendField03() >= timeThresholdMs) {
                // 满足时长阈值后，需要推送事件开始，将状态设置成null
                eventData.setStatus(EventStatus.END.getValue());
            }
        });
    }

    private void endEvent() {
        Optional.ofNullable(drivingData.getEventData(EVENT_TYPE)).ifPresent(eventData ->{
            EventConvert.convertEnd(eventData, drivingData);

            // 持续时长 > 时长阈值
            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) >= timeThresholdMs) {
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("0200停车时间{}ms,小于阈值{}ms，不进行统计", eventData.getDuration(), timeThresholdMs);
            }

            drivingData.removeEventData(EVENT_TYPE);
        });
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
    }
}
